/*
* This file is a part of the open-eBackup project.
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at
* http://mozilla.org/MPL/2.0/.
*
* Copyright (c) [2024] Huawei Technologies Co.,Ltd.
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*/
#ifndef __VDI_H__
#define __VDI_H__

#include <rpc.h>
#include <rpcndr.h>
#include "rpc.h"
#include "rpcndr.h"
#include "windows.h"
#include "ole2.h"
#include "unknwn.h"

extern "C"{
const IID IID_IClientVirtualDeviceSet = {0x40700425, 0x0080, 0x11d2, {0x85, 0x1f, 0x00,
    0xc0, 0x4f, 0xc2, 0x17, 0x59}};
const IID IID_IClientVirtualDeviceSet2 = {0xd0e6eb07, 0x7a62, 0x11d2, {0x85, 0x73, 0x00,
    0xc0, 0x4f, 0xc2, 0x17, 0x59}};

const UINT32 VD_E_NOTOPEN = 0x80770002; // The object was not open. 0x80770002
const UINT32 VD_E_TIMEOUT = 0x80770003; // The api was waiting and the timeout interval had elapsed. 0x80770003
const UINT32 VD_E_ABORT = 0x80770004; // An abort request is preventing anything except termination actions.
const UINT32 VD_E_SECURITY = 0x80770005; // Failed to create security environment. 0x80770005
const UINT32 VD_E_INVALID = 0x80770006; // An invalid parameter was supplied 0x80770006
const UINT32 VD_E_INSTANCE_NAME = 0x80770007; // Failed to recognize the SQL Server instance name 0x80770007
const UINT32 VD_E_NOTSUPPORTED = 0x80770009; // The requested configuration is invalid  0x80770009
const UINT32 VD_E_MEMORY = 0x8077000a; // Out of memory 0x8077000a
const UINT32 VD_E_UNEXPECTED = 0x8077000b; // Unexpected internal error 0x8077000b
const UINT32 VD_E_PROTOCOL = 0x8077000c; // Protocol error 0x8077000c
const UINT32 VD_E_OPEN = 0x8077000d; // All devices are open 0x8077000d
const UINT32 VD_E_CLOSE = 0x8077000e; // the object is now closed 0x8077000e
const UINT32 VD_E_BUSY = 0x8077000f; // the resource is busy 0x8077000f

typedef interface IClientVirtualDevice IClientVirtualDevice;
typedef interface IClientVirtualDeviceSet IClientVirtualDeviceSet;
typedef interface IClientVirtualDeviceSet2 IClientVirtualDeviceSet2;

#pragma pack(push, _vdi_h_)
#pragma pack(8)
struct VDConfig {
    unsigned long deviceCount;
    unsigned long features;
    unsigned long prefixZoneSize;
    unsigned long alignment;
    unsigned long softFileMarkBlockSize;
    unsigned long eomWarningSize;
    unsigned long serverTimeOut;
    unsigned long blockSize;
    unsigned long maxIODepth;
    unsigned long maxTransferSize;
    unsigned long bufferAreaSize;
};

enum VDCommands {
    VDC_READ = 1,
    VDC_WRITE = 2,
    VDC_CLEAR_ERROR = 3,
    VDC_REWIND = 4,
    VDC_WRITE_MARK = 5,
    VDC_SKIP_MARKS = 6,
    VDC_SKIP_BLOCKS = 7,
    VDC_LOAD = 8,
    VDC_GET_POSITION = 9,
    VDC_SET_POSITION = 10,
    VDC_DISCARD = 11,
    VDC_FLUSH = 12,
    VDC_SNAPSHOT = 13,
    VDC_MOUNT_SNAPSHOT = 14,
    VDC_PREPARE_TO_FREEZE = 15,
    VDC_FILE_INFO_BEGIN = 16,
    VDC_FILE_INFO_END = 17
};

struct VDC_Command {
    DWORD commandCode;
    DWORD size;
    DWORDLONG position;
    BYTE *buffer;
};

extern RPC_IF_HANDLE __MIDL_itf_vdi_0000_v0_0_c_ifspec;
extern RPC_IF_HANDLE __MIDL_itf_vdi_0000_v0_0_s_ifspec;
EXTERN_C const IID IID_IClientVirtualDevice;
MIDL_INTERFACE("40700424-0080-11d2-851f-00c04fc21759")
IClientVirtualDevice : public IUnknown {
public:
    virtual HRESULT STDMETHODCALLTYPE GetCommand(DWORD dwTimeOut, VDC_Command **ppCmd) = 0;
    virtual HRESULT STDMETHODCALLTYPE CompleteCommand(VDC_Command *pCmd, DWORD dwCompletionCode,
        DWORD dwBytesTransferred, DWORDLONG dwlPosition) = 0;
};

EXTERN_C const IID IID_IClientVirtualDeviceSet;

MIDL_INTERFACE("40700425-0080-11d2-851f-00c04fc21759")
IClientVirtualDeviceSet : public IUnknown {
public:
    virtual HRESULT STDMETHODCALLTYPE Create(LPCWSTR lpName, VDConfig *pCfg) = 0;
    virtual HRESULT STDMETHODCALLTYPE GetConfiguration(DWORD dwTimeOut, VDConfig *pCfg) = 0;
    virtual HRESULT STDMETHODCALLTYPE OpenDevice(
        LPCWSTR lpName, IClientVirtualDevice **ppVirtualDevice) = 0;
    virtual HRESULT STDMETHODCALLTYPE Close(void) = 0;
    virtual HRESULT STDMETHODCALLTYPE SignalAbort(void) = 0;
    virtual HRESULT STDMETHODCALLTYPE OpenInSecondary(LPCWSTR lpSetName) = 0;
    virtual HRESULT STDMETHODCALLTYPE GetBufferHandle(BYTE *pBuffer, DWORD *pBufferHandle) = 0;
    virtual HRESULT STDMETHODCALLTYPE MapBufferHandle(DWORD dwBuffer, BYTE **ppBuffer) = 0;
};

EXTERN_C const IID IID_IClientVirtualDeviceSet2;
MIDL_INTERFACE("d0e6eb07-7a62-11d2-8573-00c04fc21759")
IClientVirtualDeviceSet2 : public IClientVirtualDeviceSet {
public:
    virtual HRESULT STDMETHODCALLTYPE CreateEx(LPCWSTR lpInstanceName, LPCWSTR lpName, VDConfig *pCfg) = 0;
    virtual HRESULT STDMETHODCALLTYPE OpenInSecondaryEx(LPCWSTR lpInstanceName, LPCWSTR lpSetName) = 0;
};

#pragma pack(pop, _vdi_h_)
}

#endif